package com.donleo.stmg.entity.service.impl;

import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper;
import com.donleo.stmg.common.api.CommonResult;
import com.donleo.stmg.entity.model.Permission;
import com.donleo.stmg.entity.mapper.PermissionMapper;
import com.donleo.stmg.entity.service.PermissionService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.donleo.stmg.entity.vo.PermissionVo;
import com.donleo.stmg.entity.vo.TreeVo;
import com.donleo.stmg.relation.mapper.RolePermissionRelationMapper;
import com.donleo.stmg.relation.model.RolePermissionRelation;
import com.donleo.stmg.utils.CommonPath;
import com.donleo.stmg.utils.TreeUtil;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 权限表 服务实现类
 * </p>
 *
 * @author liangd
 * @since 2020-12-21
 */
@Service
public class PermissionServiceImpl extends ServiceImpl<PermissionMapper, Permission> implements PermissionService {

    @Autowired
    private PermissionMapper permissionMapper;

    @Autowired
    private RolePermissionRelationMapper rolePmsRelationMapper;

    @Override
    public List<Permission> findAll(PermissionVo permissionVo) {
        return permissionMapper.findAll(permissionVo);
    }

    @Override
    public long getCount(PermissionVo permissionVo) {
        return permissionMapper.getCount(permissionVo);
    }

    @Override
    public CommonResult add(Permission permission) {
        permission.setCreateTime(new Date());
        permission.setDataEnable(CommonPath.YES.getValue());
        int count = permissionMapper.insert(permission);
        if (count == 1) {
            return CommonResult.success(count);
        } else {
            return CommonResult.failed();
        }
    }

    @Override
    public CommonResult deletes(List<Integer> idsList) {

        List<Permission> permissionList = permissionMapper.selectBatchIds(idsList);
        List<String> collect = permissionList.stream()
                .map(Permission::getCode)
                .collect(Collectors.toList());
        List<RolePermissionRelation> list = rolePmsRelationMapper.selectByRoleCodes(collect);
        if (list.size() > 0) {
            return CommonResult.failed();
        }
        int count = permissionMapper.deleteBatchIds(idsList);
        rolePmsRelationMapper.deletes(collect);
        return CommonResult.success(count);
    }

    @Override
    public CommonResult updatePermisson(Permission permission) {
        int count = permissionMapper.updateById(permission);
        if (count == 1) {
            return CommonResult.success(count);
        } else {
            return CommonResult.failed();
        }
    }

    @Override
    public Map<String, Object> findMenuTree(Integer type) {
        Map<String, Object> map = new HashMap<>();
        //查询所有菜单
        List<Permission> lists = new LambdaQueryChainWrapper<>(permissionMapper)
                .eq(Permission::getType, 0)
                .or()
                .eq(Permission::getType, type)
                .list();
        TreeUtil menuTree = new TreeUtil();
        List<PermissionVo> pList = new ArrayList<>();
        //遍历赋值，拷贝
        setPmsData(lists, pList);
        List<Object> menuList = menuTree.menuList(pList);
        map.put("list", menuList);
        return map;
    }

    @Override
    public List<Permission> findPmsByRoleCode(String roleCode) {
        return permissionMapper.findPmsByRoleCode(roleCode);
    }

    @Override
    public CommonResult getMenuTreeData(List<TreeVo> treeVo, String roleCode, Integer type) {
        try {
            List<RolePermissionRelation> list = new ArrayList<>();
            if (type == 1) {
                //根据roleCode查菜单
                list = new LambdaQueryChainWrapper<>(rolePmsRelationMapper)
                        .eq(RolePermissionRelation::getRoleCode, roleCode)
                        .like(RolePermissionRelation::getPermissionCode, "menu:")
                        .list();
            }
            if (type == 2) {
                //根据roleCode查功能
                list = new LambdaQueryChainWrapper<>(rolePmsRelationMapper)
                        .eq(RolePermissionRelation::getRoleCode, roleCode)
                        .like(RolePermissionRelation::getPermissionCode, "method:")
                        .list();
            }
            //获取已有权限编号
            List<String> s1 = list.stream()
                    .map(RolePermissionRelation::getPermissionCode)
                    .collect(Collectors.toList());

            //获取树节点Id
            List<Integer> pmsIds = new ArrayList<>();
            for (TreeVo t : treeVo) {
                pmsIds.add(t.getId());
                getChildrenId(t, pmsIds);
            }

            //根据id集合查询权限表并获取权限编号
            List<Permission> permissionList = permissionMapper.findPmsByIds(pmsIds);
            List<RolePermissionRelation> collect = permissionList.stream().map(permission -> {
                RolePermissionRelation rpr = new RolePermissionRelation();
                rpr.setPermissionCode(permission.getCode());
                rpr.setRoleCode(roleCode);
                return rpr;
            }).collect(Collectors.toList());
            //获取树结构权限编号
            List<String> s2 = collect.stream()
                    .map(RolePermissionRelation::getPermissionCode)
                    .collect(Collectors.toList());

            //比较两个集合中相同元素和不同元素，求差值
            //s1 与 s2 的差
            Collection subtract = CollectionUtils.subtract(s1, s2);
            List<String> strings = new ArrayList<>(subtract);
            int count = 0;
            if (strings.size() != 0) {
                count = rolePmsRelationMapper.deleteByPmsCodes(strings, roleCode);
            }

            //s2 与 s1 的差
            Collection subtract1 = CollectionUtils.subtract(s2, s1);
            List<String> strings1 = new ArrayList<>(subtract1);
            List<RolePermissionRelation> rList = new ArrayList<>();
            for (String aStrings1 : strings1) {
                RolePermissionRelation pms = new RolePermissionRelation();
                pms.setRoleCode(roleCode);
                pms.setPermissionCode(aStrings1);
                rList.add(pms);
            }
            if (rList.size() != 0) {
                count = rolePmsRelationMapper.insertBatch(rList);
            }
            if (count > 0) {
                return CommonResult.success(count);
            }
            return CommonResult.success(count);
        } catch (Exception e) {
            return CommonResult.failed();
        }
    }

    @Override
    public Map<String, Object> findUserMenuPermission(String userCode) {
        List<Permission> list = permissionMapper.findUserMenuPermission(userCode);
        Map<String,Object> menuMap = new HashMap();
        TreeUtil menuTree = new TreeUtil();
        List<PermissionVo> pList = new ArrayList<>();
        //遍历赋值，拷贝
        setPmsData(list, pList);
        List<Object> menuList = menuTree.userMenuList(pList);
        menuMap.put("list", menuList);
        return menuMap;
    }

    /**
     * 赋值
     * @param list
     * @param pList
     */
    private void setPmsData(List<Permission> list, List<PermissionVo> pList) {
        for (Permission p : list) {
            PermissionVo t = new PermissionVo();
            t.setId(p.getId());
            t.setName(p.getName());
            t.setValue(p.getValue());
            t.setUri(p.getUri());
            t.setPid(p.getPid());
            pList.add(t);
        }
    }

    /**
     * 递归遍历 直到没有子节点为止
     *
     * @param t      TreeVo
     * @param pmsIds list
     */
    private void getChildrenId(TreeVo t, List<Integer> pmsIds) {
        for (TreeVo tr : t.getChildren()) {
            pmsIds.add(tr.getId());
            getChildrenId(tr, pmsIds);
        }
    }

}
